package server;

import java.io.IOException;

import server.event.MessageQoSEventListenerS2C;
import server.event.ServerEventListener;
import server.network.Gateway;
import server.network.GatewayTCP;
import server.network.GatewayUDP;
import server.network.GatewayWebsocket;
import server.qos.QoS4ReciveDaemonC2S;
import server.qos.QoS4SendDaemonS2C;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * MobileIMSDK的服务端入口主类。
 * 为了简化API的调用，理论上使用者使用本类公开的方法即可实现MobileIMSDK 的所有能力。
 * <p>
 * 本类主要实现服务端的初始化、基本服务的启停以及一些提供给开发者的公开API。
 * <p>
 * 服务端默认不会自动开启，请调用 startup()以便启动MobileIMSDK的服务端, shutdown()关闭 服务端，直到再次调用 startup() 。
 * <p>
 * 提示1： 请重写 initListeners()方法，以实现应用层的回调监听器以便实现自定义业务逻辑。
 * <p>
 * 提示2： 如要开启与MobileIMSDK-Web版的消息互通，请设置 bridgeEnabled == true ，默认为false.
 */

public abstract class ServerLauncher {
    private static Logger logger = LoggerFactory.getLogger(ServerLauncher.class);

    //    是否为消息/指令打上服务端时间戳。
    public static boolean serverTimestamp = false;


    //    当前支持的接入网关类型（即支持的网络传输协议类型）。
    public static int supportedGateways = 0;

    //    MobileIMSDK框架的核心通信逻辑实现类（实现的是MobileIMSDK服务端的通信处理核心算法）
    protected ServerCoreHandler serverCoreHandler = null;


    private boolean running = false;

    private Gateway udp = null;
    private Gateway tcp = null;
    private Gateway ws = null;

    public ServerLauncher() throws IOException {
        // default do nothing
    }

    /**
     * 初始化MobileIMSDK的ServerCoreHandler实现类。
     * 本类是MobileIMSDK的服务端网络调度算法核心所在，其性能将决定整个 即时通讯架构的数据交换性能、负载能力、吞吐效率等。
     *
     * @return
     */
    protected ServerCoreHandler initServerCoreHandler() {
        return new ServerCoreHandler();
    }

    /**
     * 初始化回调处理事件监听器。
     * 请重写 initListeners()方法，以实现应用层的回调监听器以便实现自定义业务 逻辑，可以设置的回调监听器有：
     * setServerEventListener(ServerEventListener)
     * setServerMessageQoSEventListener(MessageQoSEventListenerS2C)。
     */
    protected abstract void initListeners();


    /**
     * 初始化 网关（一个网关实例对应一种网络通信类型）。
     */
    protected void initGateways() {
        if (Gateway.isSupportUDP(supportedGateways)) {
            udp = createGatewayUDP();
            udp.init(this.serverCoreHandler);
        }

        if (Gateway.isSupportTCP(supportedGateways)) {
            tcp = createGatewayTCP();
            tcp.init(this.serverCoreHandler);
        }

        if (Gateway.isSupportWebSocket(supportedGateways)) {
            ws = createGatewayWebsocket();
            ws.init(this.serverCoreHandler);
        }
    }

    /**
     * 创建UDP协议的网关对象。
     *
     * @return
     */
    protected GatewayUDP createGatewayUDP() {
        return new GatewayUDP();
    }

    protected GatewayTCP createGatewayTCP() {
        return new GatewayTCP();
    }

    protected GatewayWebsocket createGatewayWebsocket() {
        return new GatewayWebsocket();
    }


    public void startup() throws Exception {
        if (!this.running) {
            serverCoreHandler = initServerCoreHandler();
            initListeners();
            initGateways();
            QoS4ReciveDaemonC2S.getInstance().startup();
            QoS4SendDaemonS2C.getInstance().startup(true).setServerLauncher(this);
            bind();
            this.running = true;
        } else {
            logger.warn("[IMCORE] 通信服务正在运行中，本次startup()失败，请先调用shutdown()后再试！");
        }
    }

    protected void bind() throws Exception {
        if (udp != null)
            udp.bind();
        if (tcp != null)
            tcp.bind();
        if (ws != null)
            ws.bind();
    }

    public void shutdown() {
        if (udp != null)
            udp.shutdown();
        if (tcp != null)
            tcp.shutdown();
        if (ws != null)
            ws.shutdown();

        QoS4ReciveDaemonC2S.getInstance().stop();
        QoS4SendDaemonS2C.getInstance().stop();

        this.running = false;
    }

    public ServerEventListener getServerEventListener() {
        return serverCoreHandler.getServerEventListener();
    }

    public void setServerEventListener(ServerEventListener serverEventListener) {
        this.serverCoreHandler.setServerEventListener(serverEventListener);
    }

    public MessageQoSEventListenerS2C getServerMessageQoSEventListener() {
        return serverCoreHandler.getServerMessageQoSEventListener();
    }

    public void setServerMessageQoSEventListener(MessageQoSEventListenerS2C serverMessageQoSEventListener) {
        this.serverCoreHandler.setServerMessageQoSEventListener(serverMessageQoSEventListener);
    }

    /** 获取 ServerCoreHandler 对象引用。 **/

    public ServerCoreHandler getServerCoreHandler() {
        return serverCoreHandler;
    }

    public boolean isRunning() {
        return running;
    }

//	public static void main(String[] args) throws IOException 
//    {
//        new ServerLauncher().startup();
//    }
}
